package wangwenjun.phase2.concurrencypattern.eventbus;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import util.ThreadUtil;
import wangwenjun.phase2.concurrencypattern.eventbus.framework.AsyncEventBus;
import wangwenjun.phase2.concurrencypattern.eventbus.framework.BaseEventBus;
import wangwenjun.phase2.concurrencypattern.eventbus.framework.EventBus;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author ChangLiang
 * @date 2020/6/18
 */
@Slf4j
public class AppTest {
    
    @Test
    @DisplayName("test sync event bus using SeqExecutorService")
    public void test(){
        /**
         * 其都是main线程进行执行的
         * 若其中的一个subscribe 方法运行时间比较长，则会影响
         * 下一个subscribe 方法的执行
         */
        EventBus eventBus = new BaseEventBus();
        eventBus.register(new SimpleSubscriber1());
        eventBus.register(new SimpleSubscriber2());
        eventBus.post("hello");
        eventBus.post("hello two", "test");
        log.info("finished");
    }

    @Test
    @DisplayName("test async event bus using PerThreadExecutorService")
    public void test2() throws InterruptedException {
        EventBus eventBus = new AsyncEventBus();
        eventBus.register(new SimpleSubscriber1());
        eventBus.register(new SimpleSubscriber2());
        eventBus.post("hello");
        eventBus.post("hello two", "test");
        log.info("finished");
        Thread.currentThread().join();
    }

    @Test
    @DisplayName("test async event bus using ThreadExecutorService")
    public void test3() throws InterruptedException {
        EventBus eventBus = new AsyncEventBus((ThreadPoolExecutor) Executors.newFixedThreadPool(10));
        eventBus.register(new SimpleSubscriber1());
        eventBus.register(new SimpleSubscriber2());
        eventBus.post("hello");
        eventBus.post("hello two", "test");
        log.info("finished");
        Thread.currentThread().join();
    }

    @Test
    @DisplayName("test async event bus and callback method throw RuntimeException")
    public void test4() throws InterruptedException {
        EventBus eventBus = new AsyncEventBus((t,e)->{
            log.warn("error message:{}\n, eventContext: event:[{}] post to eventBus:{} and subscribed by {} callback method:{}",
                    ThreadUtil.exceptionToString(t),e.getEvent(),e.getEventBusName(),e.getSubscriber().getClass().toString(),e.getMethod().getName());
        }, (ThreadPoolExecutor) Executors.newFixedThreadPool(10));
        eventBus.register(new SimpleSubscriber1());
        eventBus.register(new SimpleSubscriber2());
        eventBus.post("hello");
        eventBus.post("hello two", "test");
        log.info("finished");
        Thread.currentThread().join();
    }

}
